Apple, the Apple logo, and Macintosh are registered trademarks of Apple Computer, Inc.
Mac and OpenDoc are trademarks of Apple Computer, Inc.
Changes since DR2
1) Refcounting methods name change.
2) Fixed parameter passing errors of SetValue and GetValue.
About this document:
This document describes the basic usage of ODStorageUnit with actual examples and recipes. It is intended to supplement the Class Documentation. For detailed description of the ODStorageUnit methods, please refer to the Class Documentation.
Recipes / Examples
Recipe 1: Given a ODStorageUnit, create multiple Properties and Values.
su->AddProperty(ev, kODPropContents);
su->AddValue(ev, kMyKind);
su->AddValue(ev, kKindTEXT);
su->AddValue(ev, kKindPICT);
su->AddProperty(ev, kPropAnnotations);
su->AddValue(ev, kMyAnnotationsType);
Recipe 2: Given the ODStorageUnit in Recipe 1, set the focus to a certain Value.
There is more than one way to get to the value:
1) Focus the ODStorageUnit to the Value using the known Property and Type.
su->Focus(ev,
kODPropContents, // Property Name
kODPosUndefined,
kMyKind, // Value Type
0,
kODPosUndefined);
2) Focus the ODStorageUnit to the Value using the known Property and Value Index.
su->Focus(ev,
kODPropContents, // Property Name
kODPosUndefined,
kODNULL,
1, // Value Index
kODPosUndefined);
3) Focus the ODStorageUnit to the Value using the known Property and relative Position.
su->Focus(ev,
kODPropContents, // Property Name
kODPosUndefined,
kODNULL,
0,
kODPosFirstSib); // Position code
4) Focus the ODStorageUnit to the Value using a ODStorageUnitCursor. This method is especially useful when one needs to focus to a Property or a Value frequently.
One can then focus a storage unit using the created cursor:
su->FocusWithCursor(ev, cursor);
Recipe 3: Given the ODStorageUnit from Recipe 1, iterate through all the Properties.
// Unfocus storage unit
su->Focus(ev,
kODNULL,
kODPosAll, // Position Code
kODNULL,
0,
kODPosAll); // Position Code
// Get the number of Properties.
ODULong numProperties = su->CountProperties(ev);
// Iterate through the Properties
for (i = 1; i <= numProperties; i++)
{
su->Focus(ev,
kODNULL,
kODPosNextSib, // Position Code
kODNULL,
0,
kODPosUndefined);
}
Recipe 4: Given the ODStorageUnit from Recipe 1, iterate through all the Values in kODPropContents Property.
// focus to the desired Property
su->Focus(ev,
kODPropContents, // Property Name
kODPosUndefined,
kODNULL,
0,
kODPosAll); // Position code
// Get the number of Values.
ODULong numValues = su->CountValues(ev);
// Iterate through the Values
for (i = 1; i <= numValues; i++)
{
su->Focus(ev,
kODNULL,
kODPosSame, // Position code
kODNULL,
0,
kODPosNextSib); // Position code
}
Recipe 5: Given the ODStorageUnit from Recipe 1, remove the kPropAnnotationsProperty.
// focus to the desired Property
su->Focus(ev,
kPropAnnotations,
kODPosUndefined,
kODNULL,
0,
kODPosAll);
// remove the Property
su->Remove(ev);
Recipe 6: Given the ODStorageUnit from Recipe 1, remove the kKindPICT Value in kODPropContents Property.
// focus to the desired Value
su->Focus(ev,
kODPropContents,
kODPosUndefined,
kODNULL,
kKindPICT,
kODPosUndefined);
// remove the Value
su->Remove(ev);
Recipe 7: Given the focused ODStorageUnit from Recipe 2, manipulate the data in the Value. One can think of a Value as a stream. In order for Storage Units to work in a distributed environment, all the data passed in or out through the Storage Unit API are in ODByteArray. The following is the structure of an ODByteArray (from the IDL emitter):
typedef struct {
unsigned long _maximum;
unsigned long _length;
octet *_buffer;
} _IDL_SEQUENCE_octet;
typedef _IDL_SEQUENCE_octet ODByteArray;
_maximum contains the size of the memory block pointed to by _buffer.
_length contains the number of bytes (i.e., octets) of relevant data in the memory block pointed to by _buffer. This must be smaller than or equal to _maximum.
_buffer contains a pointer to a memory block whose size is reflected in _maximum.
To add data at a particular position:
su->SetOffset(ev, desiredPosition);
// Set up byte array
ODByteArray ba;
ba._length = length; // length of data to be written
ba._maximum = maximum; // maximum size of buffer
ba._buffer = buffer; // pointer to the data
su->SetValue(ev, &ba);
To add data at the current offest:
// No SetOffset is needed. Just call SetValue.
su->SetValue(ev, &ba);
To insert data at a particular position:
su->SetOffset(ev, desiredPosition);
su->InsertValue(ev, &ba);
To append data at the end of a Value:
// Get the length of the value
ODULong offset = su->GetSize(ev);
// Set the offset to the end of the value.
su->SetOffset(ev, offset);
su->SetValue(ev, &ba);
To remove data from a particular position:
su->SetOffset(ev, offset);
su->DeleteValue(ev, length);
To get data from a particular position:
// Get to the right position
su->SetOffset(ev, offset);
// Set up byte array. There is really nothing to do here
// because the fields of ODByteArray are going to be filled out by
// GetValue.
ODByteArray ba;
// Get the data.
su->GetValue(ev, desiredLength, &ba);
// Dispose the buffer created by GetValue when done.